/*
 * Copyright 2008-2009 Aying.Net Powered by Fuchun.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package net.aying.util.resources;

import java.text.MessageFormat;
import java.util.ResourceBundle;
import java.util.MissingResourceException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * 提供本地化错误信息的文本资源。
 * <p>
 * 主要目的是为了国际化日志信息、错误信息，以及简化Java的国际化调用方式，如：<br />
 * <ul>
 * <li>{@code Resources.getText(MESSAGE_NAME);}</li>
 * <li>{@code Resources.getText(MESSAGE_NAME, arg1);}</li>
 * <li>{@code Resources.getText(MESSAGE_NAME, arg1, arg2);}</li>
 * <li>... ...</li>
 * </ul>
 * </p>
 * 
 * @author Fuchun
 * @version 1.0, 2009-6-9
 */
public class Resources {

    /** {@link net.aying.util.Utils#getLength(Object)} 方法的警告信息资源Key。 */
    public static final String UTIL_WARN_GETLENGTH = "util.warn.getlength";

    /** 表示给定的 {@code URL} 不是一个合法的路径的错误信息资源Key。 */
    public static final String UTIL_ERROR_URLPATH = "util.error.urlPath";

    /** 表示给定的名称为 {@code NULL} 或者 空字符串 的错误信息资源Key。 */
    public static final String UTIL_ERROR_EMPTY_NAME = "util.error.emptyName";

    /** 表示给定的字符串不能转换成 {@code java.util.Date} 类型的错误信息资源Key。 */
    public static final String UTIL_PARSE_DATE_ERROR = "util.error.parseDate";

    /** 表示当前环境不支持特定加密算法的错误信息资源Key。 */
    public static final String UTIL_NO_SUCH_ALGORITHM = "util.error.noAlgorithm";
    
    /** 表示 {@code Crypto} 不支持特定加密(解密)算法的错误信息资源Key。 */
    public static final String UTIL_CRYPTO_NO_ALGORITHM = "util.error.cryptoNoAlgorithm";

    /** 表示无效的编码、错误的密钥长度 或者 密钥未初始化的错误信息资源Key。 */
    public static final String UTIL_ERROR_INVALID_KEY = "util.error.invalidKey";
    
    /** 表示解密用的 SecretKeySpec 对象和加密的 SecretKeySpec 不是同一个的错误信息资源Key。 */
    public static final String UTIL_ERROR_ENCRYPT = "util.error.decrypt";
    
    /** 表示要加密的文本文件不存在的错误信息资源Key。 */
    public static final String UTIL_ERROR_ENCRYPT_FILE_NOTFOUND = "util.error.encryptFileNotFound";

    private static final Log log = LogFactory.getLog(Resources.class);

    /** 本地化资源文件。 */
    private static final String RESOURCE_LOCATION = "net.aying.util.resources.Resources";

    private static final String MISSING_RESOURCE_EXCEPTION_INFO = "在国际化资源文件中，未找到给定键的对象。";

    /** class 全名的资源ResourceBundle。 */
    private static ResourceBundle rb = ResourceBundle.getBundle(RESOURCE_LOCATION);

    /**
     * 从此资源包中获取给定键的字符串。如果未找到给定键的对象，则返回空字符串。
     * 
     * @param key 所需字符串的键。
     * @return 给定键的字符串。
     */
    public static String getText(String key) {
        if (key == null || "".equals(key.trim()))
            return "";
        String message = "";
        try {
            message = rb.getString(key);
        } catch (MissingResourceException e) {
            log.warn(MISSING_RESOURCE_EXCEPTION_INFO, e);
        }
        return message;
    }

    /**
     * 从此资源包中获取给定键的带参数的字符串。如果未找到给定键的对象，则返回空字符串。
     * 
     * @param key 所需字符串的键。
     * @param args 给定键的字符串中的参数的实际值。
     * @return 给定键的带参数的字符串。
     */
    public static String getText(String key, Object... args) {
        if (key == null || "".equals(key.trim()))
            return "";
        String message = "";
        try {
            message = rb.getString(key);
            message = MessageFormat.format(message, args);
        } catch (MissingResourceException e) {
            log.warn(MISSING_RESOURCE_EXCEPTION_INFO, e);
        } catch (IllegalArgumentException e) {
            log.warn("指定的模式匹配(" + message + ")无效，或者 args 数组中的参数不是使用该参数的格式元素期望的类型。", e);
        }
        return message;
    }

    /**
     * 从此资源包中获取给定键的带一个参数的字符串。如果未找到给定键的对象，则返回空字符串。
     * 
     * @param key 所需字符串的键。
     * @param arg1 给定键的字符串中的一个参数的实际值。
     * @return 给定键的带一个参数的字符串。
     */
    public static String getMessage(String key, Object arg1) {
        return getText(key, new Object[] { arg1 });
    }

    /**
     * 从此资源包中获取给定键的带两个参数的字符串。如果未找到给定键的对象，则返回空字符串。
     * 
     * @param key 所需字符串的键。
     * @param arg1 给定键的字符串中的两个参数的实际值。
     * @return 给定键的带两个参数的字符串。
     */
    public static String getMessage(String key, Object arg1, Object arg2) {
        return getText(key, new Object[] { arg1, arg2 });
    }

    /**
     * 从此资源包中获取给定键的带三个参数的字符串。如果未找到给定键的对象，则返回空字符串。
     * 
     * @param key 所需字符串的键。
     * @param arg1 给定键的字符串中的三个参数的实际值。
     * @return 给定键的带三个参数的字符串。
     */
    public static String getMessage(String key, Object arg1, Object arg2, Object arg3) {
        return getText(key, new Object[] { arg1, arg2, arg3 });
    }

    /**
     * 从此资源包中获取给定键的带四个参数的字符串。如果未找到给定键的对象，则返回空字符串。
     * 
     * @param key 所需字符串的键。
     * @param arg1 给定键的字符串中的四个参数的实际值。
     * @return 给定键的带四个参数的字符串。
     */
    public static String getMessage(String key, Object arg1, Object arg2, Object arg3, Object arg4) {
        return getText(key, new Object[] { arg1, arg2, arg3, arg4 });
    }

    /**
     * 从此资源包中获取给定键的带五个参数的字符串。如果未找到给定键的对象，则返回空字符串。
     * 
     * @param key 所需字符串的键。
     * @param arg1 给定键的字符串中的五个参数的实际值。
     * @return 给定键的带五个参数的字符串。
     */
    public static String getMessage(String key, Object arg1, Object arg2, Object arg3, Object arg4,
            Object arg5) {
        return getText(key, new Object[] { arg1, arg2, arg3, arg4, arg5 });
    }
}
